[v26.1.x] sr/context: implement /contexts/{context}/... prefixed handlers#30363
Open
nguyen-andrew wants to merge 14 commits intoredpanda-data:v26.1.xfrom
Open
[v26.1.x] sr/context: implement /contexts/{context}/... prefixed handlers#30363nguyen-andrew wants to merge 14 commits intoredpanda-data:v26.1.xfrom
nguyen-andrew wants to merge 14 commits intoredpanda-data:v26.1.xfrom
Conversation
Collaborator
CI test resultstest results on build#83924
|
2ac2e11 to
37aa44f
Compare
Introduces context_router.h with inline helpers that will be used by
context-prefixed route wrappers:
- normalize_context(): canonicalize a URL path context parameter
by stripping outer ':' delimiters, adding '.' prefix, and
rejecting embedded colons (400 Bad Request via new
context_invalid error code)
- starts_with_context(): detect subjects already qualified with
a context prefix
Aliases like "staging", ":.staging:", and ".staging" all resolve to
the canonical form ".staging".
Includes gtest coverage for both helpers.
Includes gtest coverage for all helpers.
(cherry picked from commit cceffc0)
Adds a type-level utility for extending a std::variant with additional alternative types without repeating the original type list. This enables composing variant types where a superset variant needs all alternatives from a base variant plus extras. (cherry picked from commit c1506c2)
Splits the auth resource type into `route_resource` (route registration
time) and `resource` (authorization time). The new
`context_prefix_subject` variant in `route_resource` qualifies the
subject with the {context} path param before the ACL check runs, then
resolves to `context_subject`.
This ensures a user with ACLs on "foo" (default context) cannot access
:.staging:foo via the /contexts/.staging/subjects/foo/... URL.
(cherry picked from commit 5551d43)
Add an optional `base_path` argument to `SchemaRegistryRedpandaClient` that, when set, is prepended to every request path. This lets tests target context-prefixed routes such as `/contexts/.staging/...` without modifying call sites or duplicating the client. `SchemaRegistryEndpoints` exposes the same parameter, and `base_path` is stored via a property that strips leading and trailing slashes so callers can pass either form. Individual `request()` calls can also override the configured prefix via a `base_path=` kwarg: pass `""` to issue a single request without the prefix, or any other string to swap it for that call. The administrative endpoints (`status/ready`, `security/acls`, `contexts`) are server-global and have no context-prefixed routes, so their helpers hardcode `base_path=""` to avoid accidental prefixing when callers have set `self.base_path` for the surrounding test. (cherry picked from commit 913cedb)
Registers 15 context-prefixed routes that have a {subject} path
parameter. Each route extracts the context from the URL prefix,
scopes the subject with it via scope_subject_param(), and
delegates to the existing handler.
Covers: subject CRUD, versions, compatibility, config/{subject}, and
mode/{subject} — all via /contexts/{context}/... URLs.
Includes unit tests for scope_subject_param() and ducktape coverage
for all 15 endpoints and ACL isolation.
(cherry picked from commit 0acf252)
Registers 4 context-prefixed routes for /schemas/ids/{id} and its
sub-resources (/schema, /versions, /subjects). Adds a
scope_subject_query helper that injects the context as a "subject"
query parameter, scoping schema lookups to the specified context.
Includes unit tests for scope_subject_query and ducktape coverage
for schema lookup and sub-resource queries.
(cherry picked from commit a93647d)
Adds scope_subject_prefix_query(), which injects or prepends the
normalized context into the subjectPrefix query parameter. The
context-prefixed GET /contexts/{context}/subjects route uses this
helper to scope subject listings to the specified context.
Includes unit tests for scope_subject_prefix_query and ducktape
coverage verifying subject isolation across contexts.
(cherry picked from commit c44d2c3)
Registers context-prefixed routes for context-level config/mode and
schema types:
- GET/PUT/DELETE /contexts/{context}/config
- GET/PUT/DELETE /contexts/{context}/mode
- GET /contexts/{context}/schemas/types (pass-through)
Adds inject_context_as_subject(), which sets the subject path
parameter to a context-only qualified subject (e.g., ":.staging:").
The config and mode wrappers use this to delegate to the existing
config/mode subject handlers. Schema types are global so the context
is accepted for compatibility but ignored.
Includes unit tests for inject_context_as_subject and ducktape
coverage for all operations.
(cherry picked from commit 8e2b44b)
While implementing context-prefixed route handlers, noticed that
DELETE /contexts/{context} was not normalizing the context path
parameter before the default-context check.
Apply normalize_context() to the context path parameter before the
default-context check. This ensures alias forms like "staging",
":.staging:", and ".staging" all resolve to the same canonical context
for deletion.
Includes ducktape coverage cycling through alias forms.
(cherry picked from commit 7c2d3d8)
The v2.0.2 Schema Registry client stripped the path component from URLs (confluent-kafka-go#943), preventing context-prefixed URLs like /contexts/.serde from working. Fixed in v2.1.0 via PR redpanda-data#950. (cherry picked from commit 18720e2)
A serde client configured with schema.registry.url pointing to /contexts/.serde performs a full produce/consume round-trip. Verifies schemas are registered in the target context and isolated from the default context. Parametrized across Python, Go, and Java clients to cover all language ecosystems. (cherry picked from commit cb5aff6)
Several handlers parse the {context} path parameter and feed it to
normalize_context. Pull both steps into one helper used at the route
boundary, and have the scope_subject_* helpers take an already-normalized
context (std::string_view) so a single normalize call validates the
context before any URL rewriting.
(cherry picked from commit 955d7be)
The deferred-authz helpers (handle_get_schemas_ids_id_authz,
handle_get_subjects_authz, handle_get_contexts_authz) and several
handle_config_mode_authz call sites inside the per-request handlers
hardcoded the operation nickname against the non-prefixed route's
path_description (e.g. "get_schemas_ids_id"). With the new
/contexts/{context}/... routes registered against the same handlers,
audit log records issued via these deferred paths attributed to the
wrong nickname.
Pass the route's operation_name from the wrap class through
ctx_deferred_route, the handler entry points, and into the authz
helpers so audit events record the actual route nickname (e.g.
"ctx_get_subjects" for context-prefixed requests).
(cherry picked from commit e314131)
Add an integration test that exercises four representative
/contexts/{context}/... routes — one regular handler
(POST /subjects/{subject}/versions) and three deferred handlers
(GET /subjects, GET /schemas/ids/{id}, GET /config/{subject}) — and
verifies that each audit record uses the context-prefixed nickname
(ctx_post_subject_versions, ctx_get_subjects, ctx_get_schemas_ids_id,
ctx_get_config_subject) and an authz resource scoped to the
context-qualified subject.
(cherry picked from commit bc778c4)
37aa44f to
3316af8
Compare
Member
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Backport of PR #30189